import Parser from 'rss-parser';
import fs from 'fs';
import path from 'path';

// 解码 HTML 实体
function decodeHtmlEntities(text) {
  if (!text) return text;
  return text
    .replace(/&#8217;/g, "'")
    .replace(/&#8211;/g, "–")
    .replace(/&#8212;/g, "—")
    .replace(/&#160;/g, " ")
    .replace(/&#8230;/g, "…")
    .replace(/&#038;/g, "&")
    .replace(/&amp;/g, "&")
    .replace(/&nbsp;/g, " ")
    .replace(/&lt;/g, "<")
    .replace(/&gt;/g, ">")
    .replace(/&quot;/g, '"')
    .replace(/&#39;/g, "'");
}

// 从 HTML content 中提取第一张图片 URL
function extractImageUrl(content) {
  if (!content) return null;
  const imgMatch = content.match(/<img[^>]+src=["']([^"']+)["']/i);
  if (imgMatch && imgMatch[1]) {
    return decodeHtmlEntities(imgMatch[1]);
  }
  return null;
}

// 通用字段提取器 - 自动尝试多种可能的字段
function extractField(item, fieldNames, defaultValue = null) {
  for (const fieldName of fieldNames) {
    const value = item[fieldName];
    if (value !== undefined && value !== null && value !== '') {
      // 如果是对象，尝试提取嵌套值
      if (typeof value === 'object' && !Array.isArray(value)) {
        // 尝试常见的嵌套结构
        if (value.url) return value.url;
        if (value.$?.url) return value.$?.url;
        if (value.name) return value.name;
        if (value.text) return value.text;
      }
      // 如果是数组，取第一个
      if (Array.isArray(value) && value.length > 0) {
        const first = value[0];
        if (typeof first === 'object') {
          if (first.url) return first.url;
          if (first.$?.url) return first.$?.url;
        } else {
          return first;
        }
      }
      return value;
    }
  }
  return defaultValue;
}

// 通用图片提取器 - 尝试多种可能的图片来源
function extractImage(item) {
  // 1. 尝试 media:content (RSS 2.0 with Media RSS)
  const mediaContent = extractField(item, ['mediaContent', 'media:content']);
  if (mediaContent) {
    if (Array.isArray(mediaContent) && mediaContent[0]?.$?.url) {
      return mediaContent[0].$.url;
    }
    if (typeof mediaContent === 'string') {
      return mediaContent;
    }
  }

  // 2. 尝试 media:thumbnail
  const thumbnail = extractField(item, ['mediaThumbnail', 'media:thumbnail']);
  if (thumbnail) {
    if (typeof thumbnail === 'object' && thumbnail.$?.url) {
      return thumbnail.$.url;
    }
    if (typeof thumbnail === 'string') {
      return thumbnail;
    }
  }

  // 3. 尝试 enclosure (RSS 2.0)
  const enclosure = item.enclosure;
  if (enclosure && enclosure.url) {
    // 检查是否是图片类型
    const type = enclosure.type || '';
    if (type.startsWith('image/')) {
      return enclosure.url;
    }
  }

  // 4. 从 content/summary 的 HTML 中提取
  const content = item.content || item.summary || item.description || '';
  if (content) {
    const imgUrl = extractImageUrl(content);
    if (imgUrl) return imgUrl;
  }

  return null;
}

// 通用作者提取器
function extractAuthor(item) {
  return extractField(item, [
    'author',           // Atom feed
    'creator',          // dc:creator (RSS 2.0)
    'dc:creator',       // 直接字段
    'dc:author'         // 备用
  ]);
}

// 通用描述提取器
function extractDescription(item) {
  return extractField(item, [
    'summary',          // Atom feed
    'contentSnippet',   // RSS 2.0 (纯文本摘要)
    'description',      // RSS 2.0
    'content'           // 完整内容（作为最后备选）
  ]);
}

// 通用 RSS 解析函数
export async function parseRSSFeed(rssUrl, options = {}) {
  const {
    customFields = {},
    outputPath = null,
    verbose = false
  } = options;

  // 创建解析器，支持自定义字段
  const parserConfig = {
    customFields: {
      item: [
        ['media:content', 'mediaContent', { keepArray: true }],
        ['media:thumbnail', 'mediaThumbnail'],
        ['dc:creator', 'creator'],
        ...(customFields.item || [])
      ]
    }
  };

  const parser = new Parser(parserConfig);

  try {
    if (verbose) console.log(`正在获取 RSS 订阅: ${rssUrl}`);
    const feed = await parser.parseURL(rssUrl);

    // 统一格式化输出
    const formattedData = {
      feed: {
        title: feed.title || '',
        description: feed.description || feed.subtitle || '',
        link: feed.link || '',
        lastBuildDate: feed.lastBuildDate || feed.pubDate || feed.updated || null,
        itemCount: feed.items?.length || 0
      },
      items: feed.items.map(item => ({
        title: decodeHtmlEntities(item.title || ''),
        link: item.link || item.id || '',
        pubDate: item.pubDate || item.isoDate || item.published || null,
        author: extractAuthor(item) || null,
        description: decodeHtmlEntities(extractDescription(item) || null),
        content: item.content || null,
        guid: item.guid || item.id || item.link || null,
        imageUrl: extractImage(item) || null
      }))
    };

    // 如果指定了输出路径，保存到文件
    if (outputPath) {
      const fullPath = path.isAbsolute(outputPath) 
        ? outputPath 
        : path.join(process.cwd(), outputPath);
      // 确保目录存在
      const dir = path.dirname(fullPath);
      if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
      }
      fs.writeFileSync(fullPath, JSON.stringify(formattedData, null, 2), 'utf-8');
      if (verbose) console.log(`✅ 数据已保存到: ${fullPath}`);
    }

    return formattedData;
  } catch (error) {
    if (verbose) {
      console.error('获取 RSS 失败:', error.message);
      if (error.code === 'ENOTFOUND') {
        console.error('网络连接失败，请检查网络');
      } else if (error.code === 'ECONNREFUSED') {
        console.error('连接被拒绝，请检查 URL 是否正确');
      }
    }
    throw error;
  }
}

// 如果直接运行此文件，执行测试
const isMainModule = import.meta.url === `file://${process.argv[1].replace(/\\/g, '/')}` || 
                     process.argv[1]?.endsWith('universal-rss-parser.js');

if (isMainModule) {
  const testUrls = [
    'https://www.theverge.com/rss/index.xml',
    'https://aibusiness.com/rss.xml'
  ];

  for (const url of testUrls) {
    try {
      const data = await parseRSSFeed(url, { verbose: true });
      console.log(`\n✅ ${data.feed.title}: 获取到 ${data.items.length} 篇文章`);
      if (data.items[0]) {
        console.log(`   示例: ${data.items[0].title}`);
        console.log(`   作者: ${data.items[0].author || '未知'}`);
        console.log(`   图片: ${data.items[0].imageUrl || '无'}`);
      }
    } catch (error) {
      console.error(`❌ ${url} 解析失败:`, error.message);
    }
  }
}

